05. 类的剖析
类的剖析
开始编写你自己的 C++ 类之前,我们再看一下 Gaussian.cpp 文件中的 Gaussian 类代码。我们把类按部分分解。
gaussian.cpp 文件有以下几部分:
- 头
- 类声明
- 构造函数
- 方法定义
首先,我们看看本课程前一部分的整个 gaussian.cpp 代码:
# include <math.h>
class Gaussian
{
private:
float mu, sigma2;
public:
//构造函数
Gaussian ();
Gaussian (float, float);
//改变均差和标准偏差的值
void setMu(float);
void setSigma2(float);
//输出均差和标准偏差的值
float getMu();
float getSigma2();
//待评估函数
float evaluate (float);
Gaussian multiply (Gaussian);
Gaussian add (Gaussian);
};
Gaussian::Gaussian() {
mu = 0;
sigma2=1;
}
Gaussian::Gaussian (float average, float sigma) {
mu = average;
sigma2= sigma;
}
void Gaussian::setMu (float average) {
mu = average;
}
void Gaussian::setSigma2 (float sigma) {
sigma2= sigma;
}
float Gaussian::getMu () {
return mu;
}
float Gaussian::getSigma2() {
returnsigma2;
}
float Gaussian::evaluate(float x) {
float coefficient;
float exponential;
coefficient = 1.0 / sqrt (2.0 * M_PI * sigma2);
exponential = exp ( pow (-0.5 * (x - mu), 2) / sigma2 );
return coefficient * exponential;
}
Gaussian Gaussian::multiply(Gaussian other) {
float denominator;
float numerator;
float new_mu;
float new_var;
denominator = sigma2 + other.getSigma2();
numerator = mu * other.getSigma2() + other.getMu() * sigma2;
new_mu = numerator / denominator;
new_var =1.0/ ( (1.0/sigma2) + (1.0/other.sigma2) );
return Gaussian(new_mu, new_var);
}
Gaussian Gaussian::add(Gaussian other) {
float new_mu;
float new_sigma2;
new_mu = mu + other.getMu();
new_sigma2 = sigma2 + other.getSigma2();
return Gaussian(new_mu, new_sigma2);
}
头
在文件的顶部,你可以放置任何 include 语句以及类定义。在本例中,include 语句允许 Class 访问标准库中的数学文件。
# include <math.h>
类声明
类声明在 include 语句之后。
类声明与你已经看到的变量和函数声明类似。你需要声明所有的类变量名称、类函数名称以及它们的类型:
class Gaussian
{
private:
float mu, sigma2;
public:
//构造函数
Gaussian ();
Gaussian (float, float);
//改变均差和标准偏差的值
void setMu(float);
void setSigma2(float);
//输出均差和标准偏差的值
float getMu();
float getSigma2();
//待评估函数
float evaluate (float);
Gaussian multiply (Gaussian);
Gaussian add (Gaussian);
};
请注意,每个类的函数和变量都需要声明。所有类方法都可以使用 mu 和 sign2 这两个浮点变量;但是,一些类的函数实际上有自己的变量。一个例子是 evaluate 函数。如果你看一下 evaluate 函数的实现,你会看到这个函数有自己的变量:
float coefficient;
float exponential;
这两个变量不是类变量;coefficient 和 exponential 只能用于 evaluate 函数。
你可能已经注意到,其中一些声明在标为“private”的部分,其他声明则在标为“public”的部分。理解 private 和 public 之间的区是本课的目标之一。
构造函数
接下来是构造函数的定义。当你真正使用你的类来实例化一个对象时,这些函数会被调用。Python 有一个功能相同的语法
__init__
。
def __init__(self, variable1, variable2, ..., variablen):
第一个构造函数用于在不指定平均值和方差的情况下实例化一个对象:
Gaussian::Gaussian() {
mu = 0;
sigma2=1;
}
另一个构造函数指定在你确定平均值和方差时要执行的操作:
Gaussian::Gaussian (float average, float sigma) {
mu = average;
sigma2= sigma;
}
方法
其余代码包含你的类中所有的函数的定义,也称为方法。
get 和 set 函数专门用于获取变量或更改私有变量的值。我们会在本课后面部分详细讨论这个问题。
void Gaussian::setMu (float average) {
mu = average;
}
void Gaussian::setSigma2 (float sigma) {
sigma2= sigma;
}
float Gaussian::getMu () {
return mu;
}
float Gaussian::getSigma2() {
return sigma2;
}
其余的函数 (evaluate、multiply、add) 和 Python 的类中的函数是一样的。
float Gaussian::evaluate(float x) {
float coefficient;
float exponential;
coefficient = 1.0 / sqrt (2.0 * M_PI * sigma2);
exponential = exp ( pow (-0.5 * (x - mu), 2) / sigma2 );
return coefficient * exponential;
}
Gaussian Gaussian::multiply(Gaussian other) {
float denominator;
float numerator;
float new_mu;
float new_var;
denominator = sigma2 + other.getSigma2();
numerator = mu * other.getSigma2() + other.getMu() * sigma2;
new_mu = numerator / denominator;
new_var =1.0/ ( (1.0/sigma2) + (1.0/other.sigma2) );
return Gaussian(new_mu, new_var);
}
Gaussian Gaussian::add(Gaussian other) {
float new_mu;
float new_sigma2;
new_mu = mu + other.getMu();
new_sigma2 = sigma2 + other.getSigma2();
return Gaussian(new_mu, new_sigma2);
}